package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.GuiGuCache;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private TrackStatMapper trackStatMapper;

    /**
     * 保存专辑信息
     * @param userId
     * @param albumInfoVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(Long userId, AlbumInfoVo albumInfoVo) {

        //保存专辑信息
        AlbumInfo albumInfo = BeanUtil.copyProperties(albumInfoVo, AlbumInfo.class);
        //1.2 手动为用户id、包含声音数量（0）、是否完结、免费试听集数、审核状态（TODO：审核通过，实则有内容审核机制）
        albumInfo.setUserId(userId);
        albumInfo.setIncludeTrackCount(0);
        albumInfo.setIsFinished("0");
        albumInfo.setTracksForFree(5);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        //添加并获取专辑id
        albumInfoMapper.insert(albumInfo);
        Long albumId = albumInfo.getId();

        //保存专辑属性
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (CollectionUtil.isEmpty(albumAttributeValueVoList)){
            throw new GuiguException(500,"请选择专辑属性");
        }

        for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
            AlbumAttributeValue albumAttributeValue = BeanUtil.copyProperties(albumAttributeValueVo, AlbumAttributeValue.class);
            albumAttributeValue.setAlbumId(albumId);
            albumAttributeValueMapper.insert(albumAttributeValue);
        }

        //3.保存专辑统计信息（4条）
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_PLAY, 0);
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_SUBSCRIBE, 0);
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_BUY, 0);
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_COMMENT, 0);

        if ("1".equals(albumInfo.getIsOpen())){
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumId);
        }
    }

    /**
     * 查询用户专辑分页列表
     * @param pageInfo
     * @param albumInfoQuery
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Page<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> pageInfo, AlbumInfoQuery albumInfoQuery) {
        return albumInfoMapper.selectUserAlbumPage(pageInfo,albumInfoQuery);
    }

    /**
     * 删除专辑
     * @param albumId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAlbumInfo(Long albumId) {
        Long count = trackInfoMapper.selectCount(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, albumId));
        if (count > 0){
            throw new GuiguException(500, "该专辑下存在未删除声音！");
        }
        //删除专辑
        albumInfoMapper.deleteById(albumId);
        //删除专辑统计
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId,albumId));
        //删除专辑属性
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));

        rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId);
    }

    /**
     * 根据ID查询专辑信息
     * @param id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "album:info:")
    public AlbumInfo getAlbumInfo(Long id) {
        AlbumInfo albumInfo = albumInfoMapper.selectById(id);
        if (albumInfo != null){
            List<AlbumAttributeValue> attributeValueList = albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id));
            albumInfo.setAlbumAttributeValueVoList(attributeValueList);
        }
        return albumInfo;
    }

    /**
     * 修改专辑信息
     * @param id
     * @param albumInfoVo
     */
    @Override
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        AlbumInfo albumInfo = BeanUtil.copyProperties(albumInfoVo, AlbumInfo.class);
        albumInfo.setId(albumId);
        //修改专辑信息
        albumInfoMapper.updateById(albumInfo);

        //删除专辑属性
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
        //保存专辑属性
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (CollectionUtil.isEmpty(albumAttributeValueVoList)){
            throw new GuiguException(500,"请选择专辑属性");
        }

        for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
            AlbumAttributeValue albumAttributeValue = BeanUtil.copyProperties(albumAttributeValueVo, AlbumAttributeValue.class);
            albumAttributeValue.setAlbumId(albumId);
            albumAttributeValueMapper.insert(albumAttributeValue);
        }
        if ("1".equals(albumInfo.getIsOpen())){
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumId);
        }else {
            rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, albumId);
        }
    }

    /**
     * 获取当前用户全部专辑列表
     * @param userId
     * @return
     */
    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        //1.创建条件构造器封装查询条件
        LambdaQueryWrapper<AlbumInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlbumInfo::getUserId, userId);
        //2.指定查询字段 select 后面列名称
        queryWrapper.select(AlbumInfo::getId, AlbumInfo::getAlbumTitle, AlbumInfo::getStatus);
        //3.TODO 避免小程序响应1千多条记录导致卡顿 需要指定加载数量  limit 50
        queryWrapper.last(" limit 50");
        //4.设置排序按照最新专辑
        queryWrapper.orderByDesc(AlbumInfo::getId);
        return albumInfoMapper.selectList(queryWrapper);
    }

    /**
     * 根据专辑ID获取专辑统计信息
     * @param albumId
     * @return
     */
    @Override
    @GuiGuCache(prefix = "albumStatVo:")
    public AlbumStatVo getAlbumStatVo(Long albumId) {
        return albumInfoMapper.getAlbumStatVo(albumId);
    }

    /**
     * 查询专辑声音分页列表
     * @param userId
     * @param pageInfo
     * @param albumId
     * @return
     */
    @Override
    public Page<AlbumTrackListVo> findAlbumTrackPage(Long userId, Page<AlbumTrackListVo> pageInfo, Long albumId) {
        pageInfo =trackInfoMapper.selectTrackPage(pageInfo, albumId);
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        Assert.notNull(albumInfo, "专辑不存在", albumId);
        //获取专辑的收费情况
        String payType = albumInfo.getPayType();
        Boolean checkTrack = false;
        List<TrackInfo> trackInfos = trackInfoMapper.selectList(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, albumId));
        List<Long> trackIdList = trackInfos.stream().map(TrackInfo::getId).collect(Collectors.toList());

        //判断用户是否登录
        if (userId == null){
            if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)){
                pageInfo.getRecords().forEach(albumTrackListVo -> {
                    if (albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree()){
                        albumTrackListVo.setIsShowPaidMark(true);
                    }
                });
            }
        }else {
            //根据收费情况进行分析
            //免费不做处理
            //获取用户信息是否是vip
            UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
            Integer isVip = userInfoVo.getIsVip();

            //vip免费
            if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType)){
                if (isVip == 0 || (isVip == 1 && new Date().after(userInfoVo.getVipExpireTime()))){
                    checkTrack = true;
                }
            }
            //收费
            if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)){
                checkTrack = true;
            }
        }

        List<AlbumTrackListVo> collect = pageInfo.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum()>albumInfo.getTracksForFree()).collect(Collectors.toList());
        trackIdList = collect.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
        if (checkTrack){
            Map<Long, Integer> mapResult = userFeignClient.getUserIsPaidTrack(userId, albumId, trackIdList).getData();
            collect.stream().forEach(albumTrackListVo -> {
                Integer i = mapResult.get(albumTrackListVo.getTrackId());
                if (i.intValue() == 0){
                    albumTrackListVo.setIsShowPaidMark(true);
                }
            });
        }

        return pageInfo;
    }

    /**
     * 修改专辑统计信息
     * @param albumId
     * @param albumStatPlay
     * @param count
     */
    @Override
    public void updateAlbumStat(Long albumId, String albumStatPlay, Integer count) {
        albumStatMapper.updateAlbumStat(albumId, albumStatPlay, count);
    }

    /**
     * 获取声音统计信息
     * @param trackId
     * @return
     */
    @Override
    public TrackStatVo getTrackStatVo(Long trackId) {
        return trackStatMapper.selectTrackStatVoById(trackId);
    }



    private void saveAlbumStat(Long albumId, String statType, int statNum) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statType);
        albumStat.setStatNum(statNum);
        albumStatMapper.insert(albumStat);
    }
}
